package org.hackystat.ui.projectviewer.gwt.client.widgets;

import org.hackystat.ui.projectviewer.gwt.client.CSSStyles;
import org.hackystat.ui.projectviewer.gwt.client.common.MenuButton;

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.Widget;

/**
 * Takes care about all possible invitation actions.
 *
 * @author Pavel Senin.
 *
 */
public class InvitationActionsWidget extends Composite implements ClickListener,
                                                                    SourcesClickEvents {

  /** {@literal} ACTION_ACCEPT accept action. */
  public static final String ACTION_ACCEPT = "accept";
  /** {@literal} ACTION_DECLINE decline action. */
  public static final String ACTION_DECLINE = "decline";
  /** {@literal} ACTION_VIEW view action. */
  public static final String ACTION_VIEW = "view";

  /* The main outer pane */
  private final HorizontalPanel outer = new HorizontalPanel();
  private final HorizontalPanel inner = new HorizontalPanel();

  private static final MenuButton acceptInvitation = new MenuButton(ACTION_ACCEPT);
  private static final MenuButton declineInvitation = new MenuButton(ACTION_DECLINE);

  /* old selection handler, short term memory */
  private MenuButton oldSelectionHolder;
  private String action;

  private final ClickListenerCollection clickListeners = new ClickListenerCollection();

  /**
   * Does the menu construction.
   *
   */
  public InvitationActionsWidget() {
    outer.setStyleName(CSSStyles.ACTION_MENU_BAR);

    outer.setCellHorizontalAlignment(acceptInvitation, HorizontalPanel.ALIGN_LEFT);
    outer.setCellHorizontalAlignment(declineInvitation, HorizontalPanel.ALIGN_LEFT);

    acceptInvitation.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON);
    declineInvitation.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON);

    acceptInvitation.addClickListener(this);
    declineInvitation.addClickListener(this);

    inner.add(acceptInvitation);
    inner.add(declineInvitation);
    outer.add(inner);
    initWidget(outer);
  }

  /**
   * Menu click listener.
   *
   * @param sender The menu button clicked by user.
   */
  public void onClick(Widget sender) {

    if (sender instanceof MenuButton) {
      MenuButton mb = (MenuButton) sender;

      // "unselect" old selection
      if (null != oldSelectionHolder) {
        oldSelectionHolder.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON);
      }
      mb.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON_SELECTED);
      // memorize new selection
      oldSelectionHolder = mb;

      if (mb.equals(acceptInvitation)) {
        this.action = ACTION_ACCEPT;
        clickListeners.fireClick(this);
      }
      else if (mb.equals(declineInvitation)) {
        this.action = ACTION_DECLINE;
        clickListeners.fireClick(this);
      }
    }
  }

  /**
   * Enables or disables buttons.
   *
   * @param b True for enabling, false for disabling.
   */
  public void setMode(boolean b) {
    acceptInvitation.setEnabled(b);
    declineInvitation.setEnabled(b);
  }

  /**
   * Enables or disables Delete button.
   *
   * @param b True for enabling, false for disabling.
   */
  public void setAccept(boolean b) {
    acceptInvitation.setEnabled(b);
  }

  /**
   * Enables or disables Edit button.
   *
   * @param b True for enabling, false for disabling.
   */
  public void setDecline(boolean b) {
    declineInvitation.setEnabled(b);
  }

  /**
   * {@inheritDoc}
   */
  public void addClickListener(ClickListener listener) {
    this.clickListeners.add(listener);
  }

  /**
   * {@inheritDoc}
   */
  public void removeClickListener(ClickListener listener) {
    this.clickListeners.remove(listener);
  }

  /**
   * Report last fired action.
   *
   * @return The last fired action.
   */
  public String getAction() {
    return this.action;
  }

  /**
   * Pops all pushed buttons.
   */
  public void refreshButtons() {
    acceptInvitation.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON);
    declineInvitation.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_BUTTON);
  }

}
